//
//  PPYSigninView.swift
//  PanPanYan
//  登录信息视图,账户信息输入框+动画线条
//  Created by 向攀 on 2018/1/31.
//  Copyright © 2018年 向攀. All rights reserved.
//

import UIKit
import MBProgressHUD

enum PPYLoginType {
    case password //密码登录信息编辑视图
    case verifyCode  //验证码登录
}

//当前文本框编辑(输入)状态,和线条动画有关
enum CurrentEditStatus {
    case none
    case accountEditing
    case passwordEditing
}

class PPYSigninInfoView: UIView, UITextFieldDelegate {
    
    var loginInfoChangedHandler: ((_ isComplete: Bool) -> ())?
    
    
    private var displayLink: CADisplayLink?// = CADisplayLink()
    
    private let animationMaxCount = 20 //60=1s
    private var accountLineLeftPoint = CGPoint.zero   //账户输入下面线条左边点
    private var accountLineRightPoint = CGPoint.zero  //账户输入下面线条右边点
    private var accountOKEndPoint = CGPoint.zero      //账户输入正确动画线结束点
    private var pwdLineLeftPoint = CGPoint.zero       //密码输入下面线条左边点
    private var pwdLineRightPoint = CGPoint.zero      //密码输入下面线条左边点
    private var isDrawingLine = false
    
    private var signleLineDeltaX: CGFloat = 0         //单纯两根直线的变化值
    private var mutiLineDeltaX: CGFloat = 0           //右边有半圆的曲线的变化值
    
    private let lineWidth: CGFloat = 2              //线条宽度
    
    private var animationCount = 0                    //线条动画计时器
    
    private var circleRadius: CGFloat = 0             //圆弧线条的半径
    private var checkCircleCenter = CGPoint.zero      //账户输入正确动画圆心
    private var mutiLineCircleCenter = CGPoint.zero   //账户输入和密码输入切换动画圆弧圆心
    
    private var animationPoint = CGPoint.zero         //动画移动点坐标

    
    private let lineColor = ColorLoginBackgroundGreen             //线条颜色
    private var path = UIBezierPath()
    
    private var paths:[UIBezierPath] = []                     //存放所有路径
    private var checkPath: [UIBezierPath] = []                //账户输入正确动画路径
    
    private var isAccountFomatCorrent = false
    private var currentEditStatus = CurrentEditStatus.none
    
    
    private var type = PPYLoginType.password
    private var verifyCodeTimer: Timer?
    private var verifyCodeTimerCounter = 0
    
    //初始化,会指定高度
    init(frame: CGRect, type: PPYLoginType, loginInfoChangedHandler:((_ isComplete: Bool) -> ())?) {
        
        if frame == CGRect.zero {
            super.init(frame: CGRect(x: 24, y: 0, width: SCREEN_WIDTH - 48, height: 50))
        } else {
            super.init(frame: frame)
        }
        if frame.size.width > 370 {
            self.frame.size.width = 366
        }
        self.frame.size.height = itemHeight * 2 + itemMargin * 2
        
        self.type = type
        self.loginInfoChangedHandler = loginInfoChangedHandler
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    func setupUI() -> Void {
        backgroundColor = UIColor.clear
        backgroundColor = UIColor.white
        layer.cornerRadius = 15
        clipsToBounds = true
//        layer.addSublayer(containerView.layer)
//        addSubview(containerView)
        
        setupAccountItem()
        setupPasswordOrVerifyCodeItem()
        
        let lineDeltaHeight: CGFloat = 5 //线条整体向上平移的高度,默认线条在控件底部,但距离输入的文字距离看起来太大,所以线条整体向上平移,以靠近textfield中的文字
        
        accountLineLeftPoint = CGPoint(x: accountTextField.frame.origin.x, y: accountTextField.frame.maxY - lineDeltaHeight)
        accountLineRightPoint = CGPoint(x: accountTextField.frame.maxX, y: accountTextField.frame.maxY - lineDeltaHeight)
        pwdLineLeftPoint = CGPoint(x: passwordTextField.frame.origin.x, y: passwordTextField.frame.maxY - lineDeltaHeight)
        pwdLineRightPoint = CGPoint(x: passwordTextField.frame.maxX, y: passwordTextField.frame.maxY - lineDeltaHeight)
        signleLineDeltaX = (accountLineRightPoint.x - accountLineLeftPoint.x) / CGFloat(animationMaxCount)
        mutiLineDeltaX = (accountLineRightPoint.x - accountLineLeftPoint.x) / CGFloat(animationMaxCount / 2)
        
        //盖在控件最上方,看似无用的代码,可不能删额,实际有大用
        //有了这个,就可以手动管理输入框的输入切换(通过touchbegin...)(当然还有其他好点的方法,懒得改了)
        let coverView = UIView(frame: bounds)
        addSubview(coverView)
    }
    
    private let iconSize: CGFloat = 12
    private let itemMargin: CGFloat = 12
    private let itemHeight: CGFloat = 40
    /**
     * desp: 初始化账号输入控件
     */
    private func setupAccountItem() -> Void {
        let fieldX = itemMargin + itemMargin + iconSize
        
        accountTextField.frame = CGRect(x: fieldX, y: itemMargin, width: bounds.size.width - fieldX - itemMargin - itemMargin, height: itemHeight)
        addSubview(accountTextField)
        
        let accountIcon = UIImageView(frame: CGRect(x: itemMargin, y: itemMargin, width: iconSize, height: iconSize))
        accountIcon.image = UIImage(named: "login_account")
        addSubview(accountIcon)
        accountIcon.center = CGPoint(x: accountIcon.center.x, y: accountTextField.center.y)
        
        if type == .verifyCode {
//            let width = itemMargin + itemMargin
            let width: CGFloat = 50
            verifyCodeButton.frame = CGRect(x: bounds.size.width - width - itemMargin, y: 0, width: width, height: 20)
            verifyCodeButton.center.y = accountTextField.center.y
        } else {
        }
        
    }
    
    /**
     * desp: 初始化密码/验证码输入控件
     */
    private func setupPasswordOrVerifyCodeItem() -> Void {
        var textFieldFrame = accountTextField.frame
        textFieldFrame.origin.y = textFieldFrame.origin.y + textFieldFrame.size.height
        passwordTextField.frame = textFieldFrame
        addSubview(passwordTextField)
        passwordTextField.keyboardType = (type == .password) ? .URL : .numberPad
        if type == .password {
            passwordTextField.isSecureTextEntry = true
        }
        
        let leftIcon = UIImageView(frame: CGRect(x: itemMargin, y: itemMargin, width: iconSize, height: iconSize))
        leftIcon.image = UIImage(named: "login_password")
        addSubview(leftIcon)
        leftIcon.center = CGPoint(x: leftIcon.center.x, y: passwordTextField.center.y)
    }
    
    //MARK: - getters
    private lazy var accountTextField: UITextField = {
        let object = UITextField()
        object.font = PPYGlobalConstants.fontLevel3
        object.textColor = ColorTextLight
        object.placeholder = "mobile phone"
        object.delegate = self
        object.keyboardType = .numberPad
        object.addTarget(self, action: #selector(accountTextDidChanged(obj:)), for: .editingChanged)
        return object
    }()
    
    private lazy var passwordTextField: UITextField = {
        let object = UITextField()
        object.font = PPYGlobalConstants.fontLevel3
        object.textColor = ColorTextLight
        object.placeholder = "password"
        object.delegate = self
        object.keyboardType = .phonePad
        object.addTarget(self, action: #selector(passwordOrVerifyCodeTextDidChanged(obj:)), for: .editingChanged)
        return object
    }()
    
    private lazy var verifyCodeButton: UIButton = {
        let object = PPYTextImageOverlapButton()
        object.layer.cornerRadius = 10
        object.clipsToBounds = true
        object.titleLabel?.font = PPYGlobalConstants.fontLevel6
        object.titleLabel?.textAlignment = .center
        object.setTitle("验证码", for: .normal)
        object.setTitleColor(ColorText, for: .disabled)
        object.setTitleColor(UIColor.white, for: .normal)
        object.setImage(UIImage(named: "background_image_green"), for: .normal)
        object.setImage(UIImage(named: "background_image_gray"), for: .disabled)
        object.addTarget(self, action: #selector(getVerifyCodeClicked), for: .touchUpInside)
        object.isEnabled = false
        addSubview(object)
        return object
    }()
    
    //MARK: - 所有线条路径
    //MARK: - accountBeginLine
    //账号输入下面从左至右变长的线
    @objc func accountBeginEditAnimationLink() -> Void {
        if animationCount < animationMaxCount {
            paths.removeAll()
            isDrawingLine = true
            
            animationCount += 1
            
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: accountLineLeftPoint)
            
            animationPoint = accountLineLeftPoint
            animationPoint.x += (signleLineDeltaX * CGFloat(animationCount))
            path.addLine(to: animationPoint)
            
            paths.append(path)
        } else {
            stopAllAnimation()
            isDrawingLine = false
            path.addLine(to: accountLineRightPoint)  //保证最后是在右边的点上
        }
        setNeedsDisplay()
    }
    //MARK: - accountEndLine
    //账号输入下面从右至左变短的线
    @objc func accountEndEditAnimationLink() -> Void {
        paths.removeAll()

        if animationCount < animationMaxCount {
            isDrawingLine = true
            animationCount += 1
            
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: accountLineRightPoint)
            
            animationPoint = accountLineLeftPoint
            animationPoint.x += (signleLineDeltaX * CGFloat(animationCount))
            path.addLine(to: animationPoint)
            
            paths.append(path)
        } else {
            stopAllAnimation()
            isDrawingLine = false
        }
        setNeedsDisplay()
    }
    
    private let checkMarkShotLineUnitLength: CGFloat = 2.3 //对勾短边每个时间单位变化长度
    private let checkMarkLongLineUnitLength: CGFloat = 4.2 //对勾长边每个时间单位变化长度
    private let checkMarkLineBeginLineLength: Int = 12 //开始画对勾线时,从长横线延长的长度,同时也控制着圆弧和最终的对勾往右移的距离
    //MARK: - accountCorrectLine
    @objc func accountFormatCorrectAnimationLink() -> Void {
        isDrawingLine = true
        DispatchQueue.global().async {
            if self.animationCount < 2 { //小短横线
                self.checkPath.removeAll()
                
                self.animationPoint = self.accountLineRightPoint
                
                self.path = UIBezierPath()
                self.path.lineWidth = self.lineWidth // 3
                self.path.move(to: self.animationPoint)
                
                self.animationPoint.x += CGFloat((self.animationCount + 1) * self.checkMarkLineBeginLineLength / 2)
                
                self.path.addLine(to: self.animationPoint)
                self.checkPath.append(self.path)
                
            } else if self.animationCount < 12 {
                self.checkPath.removeAll()
                self.checkPath.append(self.path)
                
                let crlclePath = UIBezierPath()
                crlclePath.lineWidth = self.lineWidth
                let startAngle = Double.pi / Double(3)
                
                let endAngle = startAngle - Double((self.animationCount + 1) * 2) / Double(15) * Double.pi// 其中 9 = 12 / 4 * 3 (12个时间单位,一共画4/3π长度)
                crlclePath.addArc(withCenter: self.checkCircleCenter, radius: self.circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: false)
                
                self.checkPath.append(crlclePath)
            } else if self.animationCount < 15 { //开始画对勾,大圆慢慢消失
                self.checkPath.removeAll()
                
                //消失的圆弧
                let cpath = UIBezierPath()
                cpath.lineWidth = self.lineWidth
                let startAngle = Double.pi / Double(3) - Double((self.animationCount - 11) * 4) / Double(9) * Double.pi
                let endAngle = -Double.pi
                self.checkPath.append(cpath)
                
                cpath.addArc(withCenter: self.checkCircleCenter, radius: self.circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: false)
                
                //对勾短边线
                self.animationPoint = CGPoint(x: self.checkCircleCenter.x - self.circleRadius, y: self.checkCircleCenter.y)
                
                self.path = UIBezierPath()
                self.path.lineWidth = self.lineWidth
                self.path.move(to: self.animationPoint)
                
                let nextPointVerXY = CGFloat(self.animationCount - 11) * self.checkMarkShotLineUnitLength //对勾短边 长度为 7.5 * √2, 短边用时3个时间单位,所以每个时间单位x和y方向变化3
                self.animationPoint.x += nextPointVerXY
                self.animationPoint.y += nextPointVerXY
                self.path.addLine(to: self.animationPoint)
                
                self.checkPath.append(self.path)
                
            } else if self.animationCount < self.animationMaxCount { //画对勾短边,长度设置为3*(划线时间)
                self.checkPath.removeAll()
                self.checkPath.append(self.path) //短边线一直保持
                
                //对勾长边线
                self.animationPoint = CGPoint(x: self.checkCircleCenter.x - self.circleRadius, y: self.checkCircleCenter.y)
                let tempDelt = self.checkMarkShotLineUnitLength * 3 //7.5 --短边的向量x或y总长度, 单位长度(checkMarkShotLineUnitLength) * 时间(3)
                self.animationPoint.x += tempDelt
                self.animationPoint.y += tempDelt + self.lineWidth * 0.5 //短边线的终点向下移动线条宽度的一般,就是长边线的起点
                
                
                let longLinePath = UIBezierPath()
                longLinePath.lineWidth = self.lineWidth
                longLinePath.move(to: self.animationPoint)
                
                let nextPointVerXY = CGFloat(self.animationCount - 15) * self.checkMarkLongLineUnitLength //对勾长边 长度为 25 * √2, 短边用时5个时间单位,所以每个时间单位x和y方向变化3 和短边一样,复用
                self.animationPoint.x += nextPointVerXY
                self.animationPoint.y -= nextPointVerXY
                longLinePath.addLine(to: self.animationPoint)
                
                self.checkPath.append(longLinePath)
            }  else {
                DispatchQueue.main.async {
                    self.stopAllAnimation()
                }
                self.isDrawingLine = false
                return
            }
            
            DispatchQueue.main.async {
                self.animationCount += 1
                self.setNeedsDisplay()
            }
        }
    }
    
    //MARK: - accountUncorrentLine
    @objc func accountFormatUncorrectAnimationLink() -> Void {
        
        isDrawingLine = true
        DispatchQueue.global().async {
            if self.animationCount < 5 { //对勾长边消失
                if self.checkPath.count != 2 {
                    self.checkPath.removeAll()
                    self.isDrawingLine = false
                    DispatchQueue.main.async {
                        self.stopAllAnimation()
                        self.setNeedsDisplay()
                    }
                    return
                }
                let shotPath = self.checkPath.first!
                self.checkPath.removeAll()
                self.checkPath.append(shotPath) //短边线一直保持
                
                //对勾长边线
                self.animationPoint = CGPoint(x: self.checkCircleCenter.x - self.circleRadius, y: self.checkCircleCenter.y)
                let tempDelt = self.checkMarkShotLineUnitLength * 3 //解释见上面
                self.animationPoint.x += tempDelt
                self.animationPoint.y += tempDelt + self.lineWidth * 0.5 //短边线的终点,长边线的起点
                
                let longLinePath = UIBezierPath()
                longLinePath.lineWidth = self.lineWidth
                longLinePath.move(to: self.animationPoint)
                
                let nextPointVerXY = CGFloat(4 - self.animationCount) * self.checkMarkLongLineUnitLength //对勾长边 长度为 25 * √2, 短边用时5个时间单位,所以每个时间单位x和y方向变化3 和短边一样,复用
                self.animationPoint.x += nextPointVerXY
                self.animationPoint.y -= nextPointVerXY
                longLinePath.addLine(to: self.animationPoint)
                
                self.checkPath.append(longLinePath)
            } else if self.animationCount < 15 {
                self.checkPath.removeAll()
                
                //消失的圆弧
                let cpath = UIBezierPath()
                cpath.lineWidth = self.lineWidth
                let startAngle = -Double.pi
                let endAngle = -Double.pi + Double((self.animationCount - 4) * 2) / Double(15) * Double.pi
                self.checkPath.append(cpath)
                
                cpath.addArc(withCenter: self.checkCircleCenter, radius: self.circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true)
                
                if self.animationCount < 8 { //对勾短边消失
                    //对勾短边线
                    self.animationPoint = CGPoint(x: self.checkCircleCenter.x - self.circleRadius, y: self.checkCircleCenter.y)
                    
                    self.path = UIBezierPath()
                    self.path.lineWidth = self.lineWidth
                    self.path.move(to: self.animationPoint)
                    
                    let nextPointVerXY = CGFloat(7 - self.animationCount) * self.checkMarkShotLineUnitLength
                    self.animationPoint.x += nextPointVerXY
                    self.animationPoint.y += nextPointVerXY
                    self.path.addLine(to: self.animationPoint)
                    
                    self.checkPath.append(self.path)
                }
            } else if self.animationCount < self.animationMaxCount {
                self.checkPath.removeAll()
                if self.animationCount < 18 {
                    if self.animationCount < 17 { //2个时间单位显示短横线
                        self.animationPoint = self.accountLineRightPoint
                        self.animationPoint.x += CGFloat(self.checkMarkLineBeginLineLength)
                        
                        self.path = UIBezierPath()
                        self.path.lineWidth = self.lineWidth // 3
                        self.path.move(to: self.animationPoint)
                        
                        self.animationPoint.x -= CGFloat((self.animationCount - 14) * 6)
                        self.path.addLine(to: self.animationPoint)
                        self.checkPath.append(self.path)
                    } else {
                        self.checkPath.append(self.path)
                    }
                    
                    //3个时间单位消失圆弧
                    let cpath = UIBezierPath()
                    cpath.lineWidth = self.lineWidth
                    let startAngle = -Double.pi + Double((self.animationCount - 14) * 4) / Double(9) * Double.pi
                    let endAngle = Double.pi / Double(3)
                    self.checkPath.append(cpath)
                    
                    cpath.addArc(withCenter: self.checkCircleCenter, radius: self.circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true)
                    
                } else { //2个时间单位消失短横线
                    self.animationPoint = self.accountLineRightPoint
                    
                    self.path = UIBezierPath()
                    self.path.lineWidth = self.lineWidth // 3
                    self.path.move(to: self.animationPoint)
                    
                    self.animationPoint.x += CGFloat((19 - self.animationCount) * self.checkMarkLineBeginLineLength / 2)
                    self.path.addLine(to: self.animationPoint)
                    self.checkPath.append(self.path)
                }
            }  else {
                DispatchQueue.main.async {
                    self.stopAllAnimation()
                }
                self.isDrawingLine = false
                return
            }
            
            DispatchQueue.main.async {
                self.animationCount += 1
                self.setNeedsDisplay()
            }
        }
    }
    
    //MARK: - accountToPasswordLine
    @objc func passwordEditFromAccountAnimationLink() -> Void {
        isDrawingLine = true
        if animationCount < 10 {
            paths.removeAll()
            animationCount += 1
            
            //缩短的线条
            animationPoint = accountLineLeftPoint
            animationPoint.x += CGFloat(animationCount) * mutiLineDeltaX
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: animationPoint)
            
            path.addLine(to: accountLineRightPoint)
            paths.append(path)
            
            //画半圆
            path = UIBezierPath()
            path.lineWidth = lineWidth
            let startAngle = -Double.pi * 0.5
            let endAngle = startAngle + Double(animationCount) / Double(10) * Double.pi //10为画半圆用的时长
            
            path.addArc(withCenter: mutiLineCircleCenter, radius: circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true)
            paths.append(path)//添加圆弧
        } else if animationCount < animationMaxCount {
            paths.removeAll()
            
            animationCount += 1
            //画逐渐消失的半圆
            path = UIBezierPath()
            path.lineWidth = lineWidth
            let startAngle = -Double.pi * 0.5 + (Double(animationCount - 10) / Double(10) * Double.pi) //10
            let endAngle = Double.pi * 0.5
            
            path.addArc(withCenter: mutiLineCircleCenter, radius: circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true)
            paths.append(path)
            
            
            //下面变长的线条
            animationPoint = pwdLineRightPoint
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: animationPoint)
            
            animationPoint.x -= CGFloat(animationCount - 10) * mutiLineDeltaX
            path.addLine(to: animationPoint)
            paths.append(path)
        } else {
            isDrawingLine = false
            stopAllAnimation()
            return
        }
        setNeedsDisplay()
    }
    
    //MARK: - passwordBeginLine
    //直接进入密码输入,不是从账户输入完成后进入密码输入
    @objc func passwordBeginEditAnimationLink() -> Void {
        if animationCount < animationMaxCount {
            paths.removeAll()
            isDrawingLine = true
            
            animationCount += 1
            
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: pwdLineLeftPoint)
            
            animationPoint = pwdLineLeftPoint
            animationPoint.x += (signleLineDeltaX * CGFloat(animationCount))
            path.addLine(to: animationPoint)
            
            paths.append(path)
        } else {
            stopAllAnimation()
            isDrawingLine = false
            path.addLine(to: pwdLineRightPoint)  //保证最后是在右边的点上
        }
        setNeedsDisplay()
    }
    
    //MARK: - passwordEndLine
    @objc func passwordEndEditAnimationLink() -> Void {
        paths.removeAll()
        
        if animationCount < animationMaxCount {
            isDrawingLine = true
            animationCount += 1
            
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: pwdLineRightPoint)
            
            animationPoint = pwdLineLeftPoint
            animationPoint.x += (signleLineDeltaX * CGFloat(animationCount))
            path.addLine(to: animationPoint)
            
            paths.append(path)
        } else {
            stopAllAnimation()
            isDrawingLine = false
        }
        setNeedsDisplay()
    }
    
    //MARK: - passwordToAccountLine
    @objc func accountEditFromPasswordAnimationLink() -> Void {
        isDrawingLine = true
        if animationCount < 10 {
            paths.removeAll()
            animationCount += 1
            
            //缩短的线条
            animationPoint = pwdLineLeftPoint
            animationPoint.x += CGFloat(animationCount) * mutiLineDeltaX
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: animationPoint)
            
            path.addLine(to: pwdLineRightPoint)
            paths.append(path)
            
            //画半圆
            path = UIBezierPath()
            path.lineWidth = lineWidth
            let startAngle = Double.pi * 0.5
            let endAngle = startAngle - Double(animationCount) / Double(10) * Double.pi //10为画半圆用的时长
            
            path.addArc(withCenter: mutiLineCircleCenter, radius: circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: false)
            paths.append(path)//添加圆弧
        } else if animationCount < animationMaxCount {
            paths.removeAll()
            
            animationCount += 1
            //画逐渐消失的半圆
            path = UIBezierPath()
            path.lineWidth = lineWidth
            let startAngle = Double.pi * 0.5 - (Double(animationCount - 10) / Double(10) * Double.pi) //10
            let endAngle = -Double.pi * 0.5
            
            path.addArc(withCenter: mutiLineCircleCenter, radius: circleRadius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: false)
            paths.append(path)
            
            //下面变长的线条
            animationPoint = accountLineRightPoint
            path = UIBezierPath()
            path.lineWidth = lineWidth
            path.move(to: animationPoint)
            
            animationPoint.x -= CGFloat(animationCount - 10) * mutiLineDeltaX
            path.addLine(to: animationPoint)
            paths.append(path)
        } else {
            isDrawingLine = false
            stopAllAnimation()
            return
        }
        setNeedsDisplay()
    }
    
    //MARK: - 系统画图方法
    override func draw(_ rect: CGRect) {
        for path in paths {
            
            lineColor.set()
            path.stroke()
        }
        
        for path in checkPath {
            
            lineColor.setStroke()
            path.stroke()
        }
    }
    
    
    
    //MARK: - UITextFieldDelegate
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
//        print("---xp--1--------isAccount-\(textField == accountTextField)")
        if currentEditStatus == .none {
            if textField == accountTextField {
                self.accountBeginEditAnimation()
                self.currentEditStatus = .accountEditing
            } else {
                self.passwordBeginEditAnimation()
                self.currentEditStatus = .passwordEditing
            }
        } else {
            if textField == accountTextField && currentEditStatus == .passwordEditing {
                self.accountEditFromPasswordAnimation()
                self.currentEditStatus = .accountEditing
            }
            if textField == passwordTextField && currentEditStatus == .accountEditing{
                self.passwordEditFromAccountAnimation()
                self.currentEditStatus = .passwordEditing
            }
        }

//        if currentEditStatus == .none {
//            if textField == accountTextField {
//                excuteAnimationWhenLastAnimationIsFinihsed {
//                    self.accountBeginEditAnimation()
//                    self.currentEditStatus = .accountEditing
//                }
//            } else {
//                excuteAnimationWhenLastAnimationIsFinihsed {
//                    self.passwordBeginEditAnimation()
//                    self.currentEditStatus = .passwordEditing
//                }
//            }
//        } else {
//            if textField == accountTextField && currentEditStatus == .passwordEditing {
//                excuteAnimationWhenLastAnimationIsFinihsed {
//                    self.accountEditFromPasswordAnimation()
//                    self.currentEditStatus = .accountEditing
//                }
//            }
//            if textField == passwordTextField && currentEditStatus == .accountEditing{
//                excuteAnimationWhenLastAnimationIsFinihsed {
//                    self.passwordEditFromAccountAnimation()
//                    self.currentEditStatus = .passwordEditing
//                }
//            }
//
//        }
        return true
    }

    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
//        print("---xp--3--------isAccount-\(textField == accountTextField)")
//        if textField == accountTextField && currentEditStatus == .accountEditing {
//            self.currentEditStatus = .none
//            self.accountEndEditAnimation()
//            return true
//        }
//        if textField == passwordTextField && currentEditStatus == .passwordEditing {
//            self.currentEditStatus = .none
//            self.passwordEndEditAnimation()
//        }
        if textField == accountTextField && currentEditStatus == .accountEditing {
            excuteAnimationWhenLastAnimationIsFinihsed {
                self.currentEditStatus = .none
                self.accountEndEditAnimation()
            }
            return true
        }
        if textField == passwordTextField && currentEditStatus == .passwordEditing {
            excuteAnimationWhenLastAnimationIsFinihsed {
                self.currentEditStatus = .none
                self.passwordEndEditAnimation()
            }
        }
        return true
    }

    //这个方法里面的代码可要可不要,要的话,能保证输入正确和失败的动画显示完成,但是对和错切换,快速点击两次,可能只有一次点击起作用了,不要的话,就是对和错的动画可能只看到画了一部分就画另外一个动画了,其实不要还好点
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField == accountTextField && isDrawingLine {
            return false
        }
        return true
    }
    
    //MARK: - account text changed event -- 每次账户输入框的文本改变监听方法
    @objc func accountTextDidChanged(obj: NSObject) -> Void {
        validateLoginInfoComplete()
        
        if type == .verifyCode {
            
            verifyCodeButton.isEnabled = (Validate.phoneNumber(accountTextField.text).isRight && verifyCodeTimerCounter == 0)
            bringSubviewToFront(verifyCodeButton)
            return
        }
        
        if Validate.phoneNumber(accountTextField.text).isRight && isAccountFomatCorrent == false {
            self.isAccountFomatCorrent = true
            excuteAnimationWhenLastAnimationIsFinihsed {
                self.accountFormatCorrectAnimation()
            }
        } else {
            if isAccountFomatCorrent == true {
                self.isAccountFomatCorrent = false
                excuteAnimationWhenLastAnimationIsFinihsed {
                    self.accountFormatUncorrectAnimation()
                }
            }
        }
    }
    
    @objc func passwordOrVerifyCodeTextDidChanged(obj: NSObject) -> Void {
        validateLoginInfoComplete()
    }
    
    //MARK: - touch begin -- 点击事件,手动管理输入框的输入切换
    private var willChangeToStatus = CurrentEditStatus.none //将要切换到的状态,如果上次动画正在执行,则先记录此次操作希望切换到哪个状态,延时(上次的动画执行完成),再比较此时希望到达的状态是不是延时等待前的那个状态,如果是,则切换到此状态
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        let touch: UITouch = (touches as NSSet).anyObject() as! UITouch
        let touchPoint = touch.location(in: self)
        //如果textfield的UserInteractionEnabled状态变为NO,编辑中的状态会立刻变为-->willEndEditing回调......
        if accountTextField.frame.contains(touchPoint) {
            bringSubviewToFront(accountTextField)
            sendSubviewToBack(passwordTextField)
            willChangeToStatus = .accountEditing
            excuteAnimationWhenLastAnimationIsFinihsed {
                if self.willChangeToStatus == .accountEditing {
                    self.accountTextField.becomeFirstResponder()
                }
            }
            return
        }
        if passwordTextField.frame.contains(touchPoint) {
            
            bringSubviewToFront(passwordTextField)
            sendSubviewToBack(accountTextField)
            
            willChangeToStatus = .passwordEditing
            excuteAnimationWhenLastAnimationIsFinihsed {
                if self.willChangeToStatus == .passwordEditing {
                    self.passwordTextField.becomeFirstResponder()
                }
            }
        }
    }
    
    //MARK: - event
    @objc private func getVerifyCodeClicked() -> Void {
        PPYSMSTools.getVerifyCode(phoneNumber: accountTextField.text!) { (error) in
            if error == nil {
                MBProgressHUD.showSuccess(message: "验证码发送成功")
            } else {
                self.verifyCodeTimerCounter = 1
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5, execute: {
                    MBProgressHUD.showError(message: "验证码发送失败,请重试")
                })
            }
        }
        
        
        verifyCodeButton.isEnabled = false
        verifyCodeTimerCounter = 60
        self.verifyCodeButton.setTitle("\(self.verifyCodeTimerCounter)s", for: .disabled)
        if #available(iOS 10.0, *) {
            verifyCodeTimer = Timer(timeInterval: 1.0, repeats: true, block: { (timer) in
                self.verifyCodeTimerCounter -= 1
                if self.verifyCodeTimerCounter == 0 {
                    self.verifyCodeButton.setTitle("验证码", for: .disabled)
                    self.verifyCodeButton.isEnabled = Validate.phoneNumber(self.accountTextField.text).isRight
                    self.bringSubviewToFront(self.verifyCodeButton)
                    
                    self.verifyCodeTimer?.invalidate()
                    self.verifyCodeTimer = nil
                } else {
                    self.verifyCodeButton.setTitle("\(self.verifyCodeTimerCounter)s", for: .disabled)
                }
            })
            RunLoop.current.add(verifyCodeTimer!, forMode: .common)
        } else {
            // Fallback on earlier versions
        }
    }
    
    //MARK: - utility
    private func validateLoginInfoComplete() -> Void {
        if type == .password { //密码登录时输入信息改变
            let isComplete = Validate.phoneNumber(accountTextField.text).isRight && passwordTextField.text != nil && (passwordTextField.text!.count > 3) //验证手机号码和密码
            if (loginInfoChangedHandler != nil) {
                loginInfoChangedHandler!(isComplete)
            }
            return
        }
        let isComplete = Validate.phoneNumber(accountTextField.text).isRight && passwordTextField.text != nil && (passwordTextField.text!.count > 3) //验证手机号码和验证码
        if (loginInfoChangedHandler != nil) {
            loginInfoChangedHandler!(isComplete)
        }
    }
    
    func isInfomationCompleted() -> Bool {
        if type == .password { //密码登录时输入信息改变
            return Validate.phoneNumber(accountTextField.text).isRight && passwordTextField.text != nil && (passwordTextField.text!.count > 3) //验证手机号码和密码
        }
        return Validate.phoneNumber(accountTextField.text).isRight && passwordTextField.text != nil && (passwordTextField.text!.count > 3) //验证手机号码和验证码
    }
    
    func setLastLogedInUserMobile(mobile: String) -> Void {
        if Validate.phoneNumber(mobile).isRight {
            accountTextField.text = mobile
            if type == .password {
                isAccountFomatCorrent = true
                accountFormatCorrectAnimation()
            } else {
                verifyCodeButton.isEnabled = (Validate.phoneNumber(accountTextField.text).isRight && verifyCodeTimerCounter == 0)
                bringSubviewToFront(verifyCodeButton)
            }
        }
    }
    
    func getLoginInfo() -> (mobile: String, validateInfo: String)? {
        if accountTextField.text == nil || passwordTextField.text == nil {
            return nil
        }
        return (accountTextField.text!, passwordTextField.text!)
    }
    
    //MARK: - input status change event -- 所有画线条动画开始的控制,包括一些初始条件的设定
    private func stopAllAnimation() -> Void {
        animationCount = 0
        displayLink?.invalidate()
        displayLink = nil
    }
    
    private func accountBeginEditAnimation() -> Void {
        stopAllAnimation()
        
        displayLink = CADisplayLink(target: self, selector: #selector(accountBeginEditAnimationLink))
        displayLink?.add(to: RunLoop.current, forMode: .common)
    }
    
    private func accountEndEditAnimation() -> Void {
        stopAllAnimation()
        
        displayLink = CADisplayLink(target: self, selector: #selector(accountEndEditAnimationLink))
        displayLink?.add(to: RunLoop.current, forMode: .common)
    }
    
    private func accountFormatCorrectAnimation() -> Void {
        stopAllAnimation()
        
        DispatchQueue.global().async {
            let genhao3 = sin(Double.pi / Double(3)) //根号3 / 2
            self.circleRadius = CGFloat(Double(4) - genhao3 * Double(4)) * self.itemHeight//CGFloat(genhao3 * Double(2) - Double(1)) * self.itemHeight
            
            let centerX = self.accountLineRightPoint.x - (self.circleRadius * 0.5) + CGFloat(self.checkMarkLineBeginLineLength)
            let centerY = self.accountLineRightPoint.y - self.circleRadius * CGFloat(genhao3)
            
            self.checkCircleCenter = CGPoint(x: centerX, y: centerY)
            
            DispatchQueue.main.async {
                self.animationCount = 0
                self.displayLink = CADisplayLink(target: self, selector: #selector(self.accountFormatCorrectAnimationLink))
                self.displayLink?.add(to: RunLoop.current, forMode: .common)
            }
        }
    }
    
    private func accountFormatUncorrectAnimation() -> Void {
        stopAllAnimation()
        
        DispatchQueue.global().async {
            let genhao3 = sin(Double.pi / Double(3)) //根号3 / 2
            self.circleRadius = CGFloat(Double(4) - genhao3 * Double(4)) * self.itemHeight//CGFloat(genhao3 * Double(2) - Double(1)) * self.itemHeight
            
            let centerX = self.accountLineRightPoint.x - (self.circleRadius * 0.5) + CGFloat(self.checkMarkLineBeginLineLength)
            let centerY = self.accountLineRightPoint.y - self.circleRadius * CGFloat(genhao3)
            
            self.checkCircleCenter = CGPoint(x: centerX, y: centerY)
            
            DispatchQueue.main.async {
                self.animationCount = 0
                self.displayLink = CADisplayLink(target: self, selector: #selector(self.accountFormatUncorrectAnimationLink))
                self.displayLink?.add(to: RunLoop.current, forMode: .common)
            }
        }
    }
    
    private func passwordEditFromAccountAnimation() -> Void {
        stopAllAnimation()
        
        circleRadius = itemHeight * 0.5
        mutiLineCircleCenter = CGPoint(x: accountLineRightPoint.x, y: accountLineRightPoint.y + circleRadius)
        
        displayLink = CADisplayLink(target: self, selector: #selector(passwordEditFromAccountAnimationLink))
        displayLink?.add(to: RunLoop.current, forMode: .common)
    }
    
    private func passwordBeginEditAnimation() -> Void {
        stopAllAnimation()
        
        displayLink = CADisplayLink(target: self, selector: #selector(passwordBeginEditAnimationLink))
        displayLink?.add(to: RunLoop.current, forMode: .common)
    }
    
    private func passwordEndEditAnimation() -> Void {
        stopAllAnimation()
        
        displayLink = CADisplayLink(target: self, selector: #selector(passwordEndEditAnimationLink))
        displayLink?.add(to: RunLoop.current, forMode: .common)
    }
    
    private func accountEditFromPasswordAnimation() -> Void {
        stopAllAnimation()
        
        circleRadius = itemHeight * 0.5
        mutiLineCircleCenter = CGPoint(x: accountLineRightPoint.x, y: accountLineRightPoint.y + circleRadius)
        
        displayLink = CADisplayLink(target: self, selector: #selector(accountEditFromPasswordAnimationLink))
        displayLink?.add(to: RunLoop.current, forMode: .common)
    }
    
//    //    角度为贝瑟尔曲线的角度,顺时针为正角度,和数学上相反
//    func getPointOnCircle(circleCenter:CGPoint, radius: CGFloat, angle: CGFloat) -> CGPoint {
//        //        let angles = -angle//angle > 0 ? angle : -angle
//        let pointX = circleCenter.x + cos(angle) * radius
//        let pointY = circleCenter.y - sin(angle) * radius
//
//        return CGPoint(x: pointX, y: pointY)
//    }
    
    /**
     * desp: 延时执行代码,如果正在画线条的情况下
     */
    private func excuteAnimationWhenLastAnimationIsFinihsed(excuteAnimation:@escaping (() -> ())) -> Void {
        if isDrawingLine {
            if self.animationCount > 5 {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2, execute: {
                    excuteAnimation()
                })
            } else if self.animationCount > 10 {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3, execute: {
                    excuteAnimation()
                })
            }  else if self.animationCount > 15 {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.4, execute: {
                    excuteAnimation()
                })
            } else {
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1, execute: {
                    excuteAnimation()
                })
            }
        } else {
            excuteAnimation()
        }
    }
    
    private var loginCenterView: UIView?
    private var accountFomatCorrectPathBak:[UIBezierPath] = []
    //MARK: - login animation 登录整体视图变化动画
    func loginAnimation() -> Void {
        self.isUserInteractionEnabled = false
        if checkPath.count > 0 {
            accountFomatCorrectPathBak.removeAll()
            for bPath in checkPath {
                accountFomatCorrectPathBak.append(bPath)
            }
            checkPath.removeAll()
        }
        self.stopAllAnimation()
        paths.removeAll()
        setNeedsDisplay()
        currentEditStatus = .none
        
        //视图从两边压缩到中间正方形白色视图
        let cView = UIView(frame: CGRect(x: 0, y: 0, width: self.bounds.size.height, height: self.bounds.size.height))
        cView.backgroundColor = self.backgroundColor
        cView.layer.cornerRadius = 15
        cView.clipsToBounds = true
        addSubview(cView)
        cView.center = CGPoint(x: self.bounds.size.width * 0.5, y: self.bounds.size.height * 0.5)
        cView.alpha = 0.01
        loginCenterView = cView
        
        UIView.animate(withDuration: 0.25) {
            for subview in self.subviews {
//                if subview == self.containerView {
//                    continue
//                }
                subview.alpha = 0.01
            }
        }
        
        let scaleX = bounds.size.height / bounds.size.width
        UIView.animate(withDuration: 0.35, animations: {
            cView.alpha = 1.0
            self.transform = CGAffineTransform(scaleX: scaleX, y: 1)
        }) { (_) in
            self.transform = CGAffineTransform.identity
            self.backgroundColor = UIColor.clear
//            self.containerView.removeFromSuperview()
            //添加中心的转圈的加载图标
            let loadingView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
            loadingView.image = UIImage(named: "loading_black")
            self.addSubview(loadingView)
            loadingView.center = cView.center
            loadingView.alpha = 0.01
            
            let anima = CABasicAnimation()
            anima.duration = 2.5
            anima.keyPath = "transform.rotation.z"
            anima.toValue = Double.pi * Double(6)
            anima.isRemovedOnCompletion = false
            anima.repeatCount = MAXFLOAT
            loadingView.layer.add(anima, forKey: nil)
            
            UIView.animate(withDuration: 0.25, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 4, options: UIView.AnimationOptions(rawValue: 0), animations: {
                loadingView.alpha = 1.0
                cView.layer.cornerRadius = self.bounds.size.height * 0.5
            })
        }
    }
    
    //MARK: - login failed 登录失败,恢复到输入界面动画
    func loginFailedAnimation() -> Void {

        passwordTextField.text = ""
        if loginCenterView == nil {
            for subView in subviews {
                subView.alpha = 1.0
                subView.removeFromSuperview()
            }
            setupUI()
            return
        }
        
        UIView.animate(withDuration: 0.25, animations: {
            self.loginCenterView!.layer.cornerRadius = 15
        }) { (finished) in
            self.backgroundColor = self.loginCenterView?.backgroundColor
            self.loginCenterView?.removeFromSuperview()
            self.loginCenterView = nil
            
            self.transform = CGAffineTransform(scaleX: self.bounds.size.height / self.bounds.size.width, y: 1.0)
            UIView.animate(withDuration: 0.35, animations: {
                self.transform = CGAffineTransform.identity
                
            }, completion: { (finish) in
                self.stopAllAnimation()
                self.currentEditStatus = .none
                
                self.isUserInteractionEnabled = true
                for subView in self.subviews {
                    subView.alpha = 1.0 //这计划似乎会让textfield调用textFieldShouldEndEditing回调
                    subView.removeFromSuperview()
                }
                self.setupUI()
                
                if self.accountFomatCorrectPathBak.count > 0 {
                    self.checkPath.removeAll()
                    for bPath in self.accountFomatCorrectPathBak {
                        self.checkPath.append(bPath)
                    }
                    self.accountFomatCorrectPathBak.removeAll()
                    self.setNeedsDisplay()
                }
            })
        }
    }
    
}


